package 多线程练习.Restaurant;

import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

// 订单类
class Order {
    private final int id;
    private final String customerName;

    public Order(int id, String customerName) {
        this.id = id;
        this.customerName = customerName;
    }

    @Override
    public String toString() {
        return "Order{id=" + id + ", customer='" + customerName + "'}";
    }
}

// 线程安全的订单队列
class OrderQueue {
    private final Queue<Order> queue = new LinkedList<>();
    private final int maxSize;
    private final ReentrantLock lock = new ReentrantLock();

    public OrderQueue(int maxSize) {
        this.maxSize = maxSize;
    }

    // 添加订单（生产者调用）
    public void addOrder(Order order) throws InterruptedException {
        lock.lock();
        try {
            while (queue.size() >= maxSize) {
                System.out.println("队列已满，服务员等待...");
                lock.newCondition().await();
            }
            queue.offer(order);
            System.out.println("新订单加入队列: " + order);
            lock.newCondition().signalAll(); // 通知厨师
        } finally {
            lock.unlock();
        }
    }

    // 取出订单（消费者调用）
    public Order takeOrder() throws InterruptedException {
        lock.lock();
        try {
            while (queue.isEmpty()) {
                System.out.println("队列为空，厨师等待...");
                lock.newCondition().await();
            }
            Order order = queue.poll();
            lock.newCondition().signalAll(); // 通知服务员
            return order;
        } finally {
            lock.unlock();
        }
    }

    public boolean isEmpty() {
        lock.lock();
        try {
            return queue.isEmpty();
        } finally {
            lock.unlock();
        }
    }
}

// 服务员线程
class Waiter implements Runnable {
    private final OrderQueue orderQueue;
    private volatile boolean isRunning = true;
    private int orderId = 1;

    public Waiter(OrderQueue orderQueue) {
        this.orderQueue = orderQueue;
    }

    public void stop() {
        isRunning = false;
    }

    @Override
    public void run() {
        try {
            while (isRunning) {
                String customer = "顾客-" + (orderId % 5 + 1);
                Order order = new Order(orderId++, customer);
                orderQueue.addOrder(order);
                Thread.sleep(500); // 模拟接收订单间隔
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        System.out.println("服务员下班了！");
    }
}

// 厨师线程
class Chef implements Runnable {
    private final OrderQueue orderQueue;
    private volatile boolean isRunning = true;

    public Chef(OrderQueue orderQueue) {
        this.orderQueue = orderQueue;
    }

    public void stop() {
        isRunning = false;
    }

    @Override
    public void run() {
        try {
            while (isRunning || !orderQueue.isEmpty()) {
                Order order = orderQueue.takeOrder();
                System.out.println("厨师开始烹饪: " + order);
                Thread.sleep(2000); // 模拟烹饪时间
                System.out.println("烹饪完成: " + order);
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        System.out.println("厨师下班了！");
    }
}

public class test2 {
    public static void main(String[] args) throws InterruptedException {
        OrderQueue orderQueue = new OrderQueue(5); // 最大容量5

        // 创建2个服务员和3个厨师
        ExecutorService executor = Executors.newFixedThreadPool(5);
        Waiter waiter1 = new Waiter(orderQueue);
        Waiter waiter2 = new Waiter(orderQueue);
        Chef chef1 = new Chef(orderQueue);
        Chef chef2 = new Chef(orderQueue);
        Chef chef3 = new Chef(orderQueue);

        executor.execute(waiter1);
        executor.execute(waiter2);
        executor.execute(chef1);
        executor.execute(chef2);
        executor.execute(chef3);

        // 运行10秒后关闭
        Thread.sleep(10_000);
        waiter1.stop();
        waiter2.stop();
        chef1.stop();
        chef2.stop();
        chef3.stop();

        executor.shutdown();
        if (!executor.awaitTermination(5, TimeUnit.SECONDS)) {
            System.out.println("强制关闭剩余任务！");
            executor.shutdownNow();
        }
        System.out.println("餐厅打烊！");
    }
}
